package com.exmaple.excel.jxls;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.jxls.area.Area;
import org.jxls.builder.AreaBuilder;
import org.jxls.builder.xls.XlsCommentAreaBuilder;
import org.jxls.common.CellRef;
import org.jxls.common.Context;
import org.jxls.transform.Transformer;
import org.jxls.transform.poi.PoiContext;
import org.jxls.transform.poi.PoiTransformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.Map;

/**
 * @author Create By Liuqz
 * @date 2019/1/11 20:24
 */
public class ExcelUtilForJxls {

    static Logger log = LoggerFactory.getLogger(ExcelUtilForJxls.class);


    /**
     * @param tmplPath    模板读取路径
     * @param tmplName    模板名称(不包含后缀)
     * @param objFilePath 目标文件生成路径
     * @param objFileName 目标文件名(不包含后缀)
     * @param paramMap    待生成数据集合(map数据源)
     * @param response
     * @return 0导出成功|1某参数为空|2系统异常|-1模板文件不存在
     * @Description:导出Excel方法
     * @Auther: wuhangyu
     * @Date: 2016-4-25 下午3:16:54
     */
    public int exportExcel(String tmplPath, String tmplName, String objFilePath, String objFileName, String expSheetName, List<Map<String, Object>> exportList, HttpServletResponse response) {
        log.info("--------------导出文件---------begin----");
        //参数非空
        if (tmplPath.equals(null) || tmplName.equals(null) || objFilePath.equals(null) || objFileName.equals(null) || exportList.equals("null") || exportList.size() < 1 || exportList == null || response == null) {
            log.info("传入参数有误或有空值，中断执行");
            return 1;
        }
        if ("".equals(expSheetName) || null == expSheetName) {
            expSheetName = "report";
        }
        //模板路径及名称
        tmplPath = tmplPath + "/" + tmplName;

        log.info("模板文件存放目录:" + tmplPath);
        //目标路径及名称
        String mbFilePath = objFilePath + "/" + objFileName;
        log.info("目标文件生成目录:" + mbFilePath);
        OutputStream outputStream = null;
        FileOutputStream fos = null;
        try {
            //检测模板文件是否存在
            File lcfile = new File(tmplPath);
            if (!lcfile.exists()) {
                log.error("模板文件不存在,请确认其位置");
                return -1;
            }
            //检测目标路径是否存在，不存在则创建
            File file = new File(objFilePath);
            log.info("检测目标路径是否存在:" + file.exists());
            log.info("检测路径是否是一个目录:" + file.isDirectory());
            if (!file.exists() && !file.isDirectory()) {
                log.info("创建目录:" + objFilePath);
                file.mkdirs();
            }
            log.info("检测目标路径是否存在:" + file.exists());
            log.info("检测路径是否是一个目录:" + file.isDirectory());
            response.setHeader("Content-Disposition", "attachment;fileName=" + new String(objFileName.getBytes("GBK"), "ISO8859-1"));
            response.setContentType("application/octet-stream");
            outputStream = response.getOutputStream();
            fos = new FileOutputStream(mbFilePath);
            InputStream is = new FileInputStream(tmplPath);
            Workbook workbook = WorkbookFactory.create(is);
            Transformer transformer = PoiTransformer.createSxssfTransformer(workbook, exportList.size() + 5, true);
            Workbook workbook2 = ((PoiTransformer) transformer).getWorkbook();
            AreaBuilder areaBuilder = new XlsCommentAreaBuilder(transformer);
            List<Area> xlsAreaList = areaBuilder.build();
            Area xlsArea = xlsAreaList.get(0);
            Context context = new PoiContext();
            context.putVar("exportList", exportList);
            long startTime = System.nanoTime();
            xlsArea.applyAt(new CellRef(expSheetName + "!A1"), context);
            workbook2.removeSheetAt(2);
            workbook2.removeSheetAt(1);
            workbook2.removeSheetAt(0);
            long endTime = System.nanoTime();
            log.info("Sxssf  花费时间(秒): " + (endTime - startTime) / 1000000000);
            workbook2.write(fos);
            FileInputStream os2 = new FileInputStream(mbFilePath);
            byte[] b = new byte[1024];
            int i = 0;
            while ((i = os2.read(b)) > 0) {
                outputStream.write(b, 0, i);
            }
            fos.flush();
            os2.close();
            outputStream.flush();
        } catch (FileNotFoundException e) {
            log.error("excel文件目录出错：" + e.getMessage());
            return 2;
        } catch (InvalidFormatException e) {
            log.error("未知异常：" + e.getMessage());
            return 2;
        } catch (IOException e) {
            log.error("IO流错误：" + e.getMessage());
            return 2;
        } finally {
            log.info("导出成功,文件生成目录:" + mbFilePath);
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                }
            }
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                }
            }
        }
        log.info("--------------导出文件---------end----");
        return 0;
    }


}
